/**
 * 
 */
package com.ffcs.crmd.tsp.task.netty.processor;

import java.util.Map;

import org.slf4j.Logger;

import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailThreadInfo;
import com.ffcs.crmd.tsp.api.dto.client.TspThreadInfo;
import com.ffcs.crmd.tsp.api.dto.job.TspJobDetailShell;
import com.ffcs.crmd.tsp.api.dto.netty.RemotingCommand;
import com.ffcs.crmd.tsp.api.netty.INettyProcessor;
import com.ffcs.crmd.tsp.api.netty.INettyRemotingClient;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.netty.ResponseCode;
import com.ffcs.crmd.tsp.core.util.XmlUtil;
import com.ffcs.crmd.tsp.task.container.ThreadPoolContainer;
import com.ffcs.crmd.tsp.task.job.BusinessProcessor;
import com.ffcs.crmd.tsp.task.log.TaskLogger;
import com.ffcs.crmd.tsp.task.threadpool.JobProcessBusinessThreadPool;
import com.ffcs.crmd.tsp.task.threadpool.JobProcessThreadPool;
import com.ffcs.crmd.tsp.task.threadpool.JobRunnablePair;
import com.ffcs.crmd.tsp.task.threadpool.api.IJobProcessRunnable;

import io.netty.channel.ChannelHandlerContext;

/**
 * 功能说明:获取子任务运行线程信息处理者
 *
 * @author ZHONGFUHUA
 * 
 * @since 2.0.0-SNAPSHOT
 *
 */
public class QueryJobDetailThreadInfoProcessor implements INettyProcessor {

    /**
     * 日志
     */
    private static final Logger          LOG                          = TaskLogger.getLogger(LoggerName.TaskLoggerName);
    
    /**
     * 任务处理线程池
     */
    private JobProcessThreadPool         jobProcessThreadPool         = ThreadPoolContainer.getInstance().getJobProcessThreadPool();
    
    /**
     * 任务批量业务处理线程池
     */
    private JobProcessBusinessThreadPool jobProcessBusinessThreadPool = ThreadPoolContainer.getInstance().getJobProcessBusinessThreadPool();
    
    /**
     * 功能说明:
     * 
     * @param nettyRemotingClient
     */
    public QueryJobDetailThreadInfoProcessor(INettyRemotingClient nettyRemotingClient) {
        
    }
    
    @Override
    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
        TspJobDetailShell tspJobDetailShell = XmlUtil.fromXml(new String(request.getBody()), TspJobDetailShell.class);
        LOG.debug("TASK-NETTY: recive a request to get job detail[{}] thread info opaque=[{}] id=[{}].",
            tspJobDetailShell.getContext().getTspJobInstance().getJobKey(), request.getOpaque(),
            tspJobDetailShell.getId());
        
        
        TspJobDetailThreadInfo tspJobDetailThreadInfo = new TspJobDetailThreadInfo();
        JobRunnablePair jobRunnablePair = jobProcessThreadPool.getThread(tspJobDetailShell.getId());
        if(jobRunnablePair != null){
            TspThreadInfo tspThreadInfo = new TspThreadInfo();
            tspThreadInfo.setId(jobRunnablePair.getThread().getId());
            tspThreadInfo.setName(jobRunnablePair.getThread().getName());
            tspThreadInfo.setGroupName(jobRunnablePair.getThread().getThreadGroup().getName());
            tspThreadInfo.setState(jobRunnablePair.getThread().getState().toString());
            tspJobDetailThreadInfo.setJobProcessThread(tspThreadInfo);
            IJobProcessRunnable jobProcessRunnable = jobRunnablePair.getRunnable();
            Map<BusinessProcessor<Object>, Object> businessProcessThradMap = jobProcessRunnable.getBusinessProcessThreadMap();
            for(Object object : businessProcessThradMap.values()){
                Thread thread = jobProcessBusinessThreadPool.getThread(object);
                TspThreadInfo jobProcessBusinessThread = new TspThreadInfo();
                jobProcessBusinessThread.setId(thread.getId());
                jobProcessBusinessThread.setName(thread.getName());
                jobProcessBusinessThread.setGroupName(thread.getThreadGroup().getName());
                jobProcessBusinessThread.setState(thread.getState().toString());
                tspJobDetailThreadInfo.getJobProcessBusinessThread().add(jobProcessBusinessThread);
            }
        }
        
        RemotingCommand response = RemotingCommand.createResponseCommand(ResponseCode.SUCCESS);
        response.setBody(XmlUtil.toXml(tspJobDetailThreadInfo).getBytes());
        return response;
    }
    
}
